package de.unimannheim.ki.algorithmn;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import weka.associations.AssociationRule;
import weka.associations.AssociationRules;
import weka.associations.BinaryItem;
import weka.associations.FPGrowth;
import weka.associations.Item;


import de.unimannheim.ki.databaseentities.MusicObject;
import de.unimannheim.ki.databaseentities.Musicuser;
import de.unimannheim.ki.usermanagement.DatabaseUserDAO;

public class LikeAssociationJoint implements IComparator {
	public FPGrowth model;
	HashMap<String, List<String>> relatedMatrix;
	
	public LikeAssociationJoint(FPGrowth model, DatabaseUserDAO dao) {
		this.model = model;
		relatedMatrix = new HashMap<String, List<String>>();
		this.getrelatedMatrix(dao.getAllObjects());
	}


	@Override
	public List<Neighbour> computeDistance(List<Musicuser> users,
			Musicuser compareuser) {
		
		
			ArrayList<Neighbour> neighbours = new ArrayList<Neighbour>();
			//get the liked objects of the user 
			List<MusicObject> myLikedObjects = compareuser.getObjects();
		
			//loop over users to compare with
			for (int i = 0; i < users.size(); i++) {
				
				double likeQuota = 0.0;
				// get current user
				Musicuser mu = users.get(i);
				// if same user continue
				if (mu.getFbid().equals(compareuser.getFbid()))
					continue;
				
				//get the likes of mu
				List<MusicObject> muLikes = mu.getObjects();
				
				double overallrelationrate = 0.0;
				int directrelations = 0;
				int indirectrelations = 0;
				int totalpairs= 0;
				int numberofitemsrelated = 0;
				//loop over the likes of the current user
				for (MusicObject myobject : myLikedObjects) {
					
					for (MusicObject userobject : muLikes) {	
						
						if(userobject.getId() == myobject.getId()){
							directrelations++;
						} else {
							if(isrelated(myobject.getId()+"",userobject.getId()+"" )){
								indirectrelations++;
							}
						}
						totalpairs++;
					}
					/*
					//first check wether the item is in the compareusers list
					//if(muLikes.contains(myobject)) {
						directrelations++;
					}else {
					
					
					//get related items to the current object
					List<String> relateditems = getrelatedItemsNew(myobject.getId()+"");
				//	System.out.println("Size" + relateditems.size());
					
					//loop over the object of the user to compare with
						for (String item : relateditems) {
							for (MusicObject userobject : muLikes) {	
								if (item.equals(userobject.getId()+"")){
								numberofitemsrelated++;
							}
							}
						}
					}
					
				}// object compare
				*/
				}//object compare
				if(totalpairs== 0){
					overallrelationrate = 0.0;
				}else {
					overallrelationrate  =  (double) ( ((double) directrelations) +((double) indirectrelations)) / ((double) totalpairs);
				}
				neighbours.add(new Neighbour(overallrelationrate, mu));
			
			}// loop over users
			Collections.sort(neighbours);
		return neighbours;
	}
	private boolean isrelated(String ia, String ib){
		List<String> relateditems = getrelatedItemsNew(ia);
		return relateditems.contains(ib);
	}
	
	private void getrelatedMatrix(List<MusicObject> allObjects){
		
		//init Map
		for (MusicObject musicObject : allObjects) {
			relatedMatrix.put(musicObject.getId()+"", new ArrayList<String>());
		}
		List<String> relateditems = null;
		List<AssociationRule> rules = model.getAssociationRules().getRules();
		for (AssociationRule rule : rules) {
			for(Item item: rule.getPremise() ){
				relateditems = relatedMatrix.get(item.getAttribute().name().substring(1));
				for(Item item2: rule.getConsequence() ){
					if(!relateditems.contains(item2.getAttribute().name().substring(1))){
						relateditems.add(item2.getAttribute().name().substring(1));
					}
				}
				relatedMatrix.put(item.getAttribute().name().substring(1), relateditems);
			}
		}
		
	}
	private List<String> getrelatedItemsNew(String attributeid){
		return relatedMatrix.get(attributeid);
	}
//	private List<String> getrelatedItems (String attributeid){
//		boolean isinPremise = false;
//		boolean isinConsequence = false;
//
//		
//		//model.
//		AssociationRules test = model.getAssociationRules();
//	
//		List<AssociationRule> rules =	test.getRules();
//		List<String> itemsrelated = new ArrayList<String>();
//		for (AssociationRule rule : rules) {
//			Collection<BinaryItem> tester = rule.getPremise();
//			
//			
//			for (BinaryItem item : tester) {
//				if(item.getAttribute().name().equals(attributeid)){
//					 isinPremise = true; 
//					 break;
//				}
//			}
//			
//			tester = rule.getConsequence();
//			for (BinaryItem item : tester) {
//				if(item.getAttribute().name().equals(attributeid)){
//					isinConsequence = true; 
//					 break;
//				}
//			}
//			if(isinPremise || isinConsequence){
//				tester = rule.getConsequence();
//				for (BinaryItem item : tester) {
//					if( !itemsrelated.contains(item.getAttribute().name()))
//					itemsrelated.add(item.getAttribute().name());
//				}
//				
//				tester = rule.getPremise();
//				for (BinaryItem item : tester) {
//					if( !itemsrelated.contains(item.getAttribute().name()))
//					itemsrelated.add(item.getAttribute().name());
//				}
//				 isinConsequence = false;
//				 isinPremise = false;
//			}
//			
//			//tester = rule.getConsequence()
//		}//items related get
//		
//		/*System.out.println("Itemrelated:");
//		for (String string : itemsrelated) {
//			System.out.println(string);
//		}*/
//		
//		return itemsrelated;
//	}

}
